#include "khan.hpp"
#include "command2.hpp"

extern match_type cmd_ipv4_match (const std::string str);
void print_cmds(int num, cmd_list_t cmds);

void tst_ipv4()
{
    char* ipv4_tst1 = (char*)"192";
    char* ipv4_tst2 = (char*)"192.18";
    char* ipv4_tst3 = (char*)"192.18.";
    char* ipv4_tst4 = (char*)"192.18.23.233";
    char* ipv4_tst5 = (char*)"192.18.23.233.23";
    char* ipv4_tst6 = (char*)"192.18.23.";
    char* ipv4_tst7 = (char*)"192.18.8323.32";
    char* ipv4_tst8 = (char*)"192.18.adb.32";

    assert(cmd_ipv4_match(ipv4_tst1) == partly_match);
    assert(cmd_ipv4_match(ipv4_tst2) == partly_match);
    assert(cmd_ipv4_match(ipv4_tst3) == partly_match);
    assert(cmd_ipv4_match(ipv4_tst4) == exact_match);
    assert(cmd_ipv4_match(ipv4_tst5) == no_match);
    assert(cmd_ipv4_match(ipv4_tst6) == partly_match);
    assert(cmd_ipv4_match(ipv4_tst7) == no_match);
    assert(cmd_ipv4_match(ipv4_tst8) == no_match);
}

void tst_cmd_node()
{
    command2_ptr p(new command2());
    command2_ptr c(new command2("<10-50>", "port number\n"));
    p->add_child(c);

    std::string tmp("0");
    assert(c->mathed("0") == no_match);
    tmp.assign("1");
    assert(c->mathed(tmp) == no_match);
    tmp.assign("38");
    assert(c->mathed(tmp) == exact_match);
    tmp.assign("380000");
    assert(c->mathed(tmp) == no_match);

    command2_ptr ipc(new command2("X.X.X.X", "ip address\n"));
    p->add_child(ipc);

    tmp.assign("192");
    assert(ipc->mathed(tmp) == partly_match);
    tmp.assign("192.1");
    assert(ipc->mathed(tmp) == partly_match);
    tmp.assign("192.168.");
    assert(ipc->mathed(tmp) == partly_match);
    tmp.assign("192.168.3.");
    assert(ipc->mathed(tmp) == partly_match);
    tmp.assign("192.168.3.22");
    assert(ipc->mathed(tmp) == exact_match);
    tmp.assign("192.168.333.22");
    assert(ipc->mathed(tmp) == no_match);
    tmp.assign("192.16a.333.22");
    assert(ipc->mathed(tmp) == no_match);
    tmp.assign("19216a.333.22");
    assert(ipc->mathed(tmp) == no_match);
    tmp.assign("");
    assert(ipc->mathed(tmp) == no_match);

    command2_ptr cmd(new command2("route", "ip address\n"));
    p->add_child(cmd);

    tmp.assign("r");
    assert(cmd->mathed(tmp) == partly_match);
    tmp.assign("rou");
    assert(cmd->mathed(tmp) == partly_match);
    tmp.assign("route");
    assert(cmd->mathed(tmp) == exact_match);
    tmp.assign("routeha");
    assert(cmd->mathed(tmp) == extend_match);
    tmp.assign("hello");
    assert(cmd->mathed(tmp) == no_match);

    command2_ptr strcmd(new command2("HELLO", "string\n"));
    p->add_child(strcmd);
    
    tmp.assign("");
    assert(strcmd->mathed(tmp) == no_match);
    tmp.assign("helloadf");
    assert(strcmd->mathed(tmp) == partly_match);
    

    printf("++++++++++++++++++++++++++++++++\n");

    cmd_list_t cmds;
    int num = p->find_children(partly_match, "192.168.", cmds);
    print_cmds(num, cmds);
    assert(num == 2);
    cmds.clear();

    num = p->find_children("19", cmds);
    print_cmds(num, cmds);
    assert(num == 3);
    cmds.clear();

    num = p->find_children(partly_match, "rou", cmds);
    print_cmds(num, cmds);
    assert(num == 2);
    cmds.clear();
};

void print_cmds(int num, cmd_list_t cmds)
{
    cmd_list_iterator iter = cmds.begin();
    for (int idx=0; iter != cmds.end(); idx++, iter++) {
        PDBG("num: %d, idx:%d, cmds: %s\n", num, idx, (*iter)->get_cmd().c_str());
    }
}
